////*******************************************************************
//// Definition of color pattern and sequences
////*******************************************************************

uint8_t  diff(uint8_t a, uint8_t b)
{
    if (a <= b) return (b - a);
    else        return (a - b);
}

/**
* @brief Clear the entire stripe.
*/
void clearStripe(void)
{
  strip.clear();
}

/**
* Vertical flashing Circle 
* @param color Value for Color
* @param delaytime Time between two Leds switching on
*/
void vertCircle(rgb_t color, uint16_t delaytime)
{
   int pos;
   uint8_t stripe;
   for (pos=1; pos<= LEDS_PER_STRIPE; pos++)
   {
        for (stripe = 1; stripe<= STRIPES; stripe++)
		strip.setPixelColor(pos, color, stripe);	
	strip.show();
 	delay(delaytime);
        
        for (stripe = 1; stripe<= STRIPES; stripe++)  
	  strip.setPixelColor(pos, {0,0,0}, stripe);
	strip.show();
	delay(delaytime / 2);
   }
}


/**
* Inverted Vertical flashing Circle 
* @param color Value for Color
* @param delaytime Time between two Leds switching on
*/
void vertCircleRev(rgb_t color, uint16_t delaytime)
{
   int pos;
   uint8_t stripe;
   for (pos=LEDS_PER_STRIPE; pos > 0;  pos--)
   {
     for (stripe = 1; stripe<= STRIPES; stripe++)
		strip.setPixelColor(pos, color, stripe);
     strip.show();
     delay(delaytime);
     
     for (stripe = 1; stripe<= STRIPES; stripe++)
  		strip.setPixelColor(pos, {0,0,0}, stripe);
     strip.show();
     delay(delaytime / 2);
   }
}

/**
* Horizontal flashing Circle 
* @param color Value for Color
* @param delay_ms Time between two Leds switching on
*/
void horCircle(rgb_t color, uint16_t delay_ms)
{
	uint8_t stripe;
	 
        for (stripe=1; stripe<=STRIPES; stripe++)
	{
			
	    strip.setStripeColor(color, stripe);
	    strip.show();
	    delay(delay_ms);
	    strip.setStripeColor({0,0,0},stripe);
	    strip.show();
	    delay(delay_ms / 2);
	}	
}


/**
 * @brief Random Color and Position
 * @param color Set Color value limit for each base color
 * @param ms Delay between next calculation
 * @param fade Enable/Disable Color fading
 * @param clr Enable/Disable clearing entire stripe before setting color
 */
void rand(rgb_t color, uint16_t ms, bool fade, bool clr)
{
  rgb_t c = {0,0,0};
  uint8_t pos = random(0, STRIPSIZE-1);

  if (color.r)
    c.r = random(0,color.r);
  if (color.g)
    c.g = random(0,color.g);
  if (color.b)
    c.b = random(0,color.b);
    
  if (clr)
    strip.clear();
   
  if (fade)
  {
    rgb_t  oc; // old color value
    bool r_fin = false;
    bool g_fin = false;
    bool b_fin = false;
    if(clr) 
      oc = {0,0,0};
    else
      oc = strip.getPixelColor(pos); // old color value
   
      
    // fade in
    while (!r_fin && !g_fin && !b_fin)
    { 
       if (oc.r == c.r) 
           r_fin = true;   // red value reached
       else
       {  
           if (oc.r < c.r) 
              oc.r++;
           else 
              oc.r--;
       }
      if (oc.g == c.g) 
          g_fin = true;  // green value reached
      else 
      {
          if (oc.g < c.g) 
              oc.g++;
          else 
              oc.g--;
      }

      if (oc.b == c.b)
           b_fin = true;      // blue value reached
      else
      {  
          if (oc.b < c.b) 
              oc.b++;
          else 
              oc.b--;
      }
            
      strip.setPixelColor(pos,oc);
      strip.show();
      delay(ms);
    }
    
    // fade out when clear option is set
    if (clr)
    {
      r_fin = false;
      g_fin = false;
      b_fin = false;
      
      while(!r_fin && !g_fin && !b_fin)
      {
        if (oc.r > 0)
          oc.r--;
        else 
          r_fin = true;
        if (oc.g > 0)
          oc.g--;
        else 
          g_fin = true;
        if (oc.b > 0)
          oc.b--;
        else 
          r_fin = true;
          
        strip.setPixelColor(pos,oc);
        strip.show();
        delay(ms);                 
      }
    }   
  }
  else 
  {
    strip.setPixelColor(pos,c);
    strip.show();    
    delay(ms);    
  } 
}



/**
 * @brief Randomized Color for all stripes with fading
 * @param climit Limits the random color generator
 */
void glowGlobe(rgb_t climit)
{
    static rgb_t current, next; // current and next color
    static bool run = false;    // flag for init this function
    uint8_t stripe;
    
    
    if(!run)
    {
      current = strip.getPixelColor(0);
      next.r = random(0,climit.r);
      next.g = random(0,climit.g);
      next.b = random(0,climit.b);
      run = true;
    }

      if(current.r != next.r) //next red value not reached
      {
         if(current.r < next.r)
           current.r++;
         else 
           current.r--;           
      }
      else 
        do {next.r = random(0,climit.r); } while( diff(next.r, current.g) < 20);  // make a little bit more color different
    
      if(current.g != next.g) //next green value not reached
      {
         if(current.g < next.g)
           current.g++;
         else 
           current.g--;           
      }
      else 
        do {next.g = random(0,climit.g); } while( diff(next.g, current.b) < 20);  // make a little bit more color different
    
      if(current.b != next.b) //next blue value not reached
      {
         if(current.b < next.b)
           current.b++;
         else 
           current.b--;           
      }
      else 
        do {next.b = random(0,climit.b); } while( diff(next.b, current.r) < 20);  // make a little bit more color different
     
     for(stripe=1; stripe<=STRIPES; stripe++)
        strip.setStripeColor(current,stripe);
     strip.show();      
        
}

/** 
 * @brief Rotates a single Pixel around. Does not activate (show()) the output.
 *        This must be done from calling function.
 * @param color Pxel Color 
 * @param line Rotating Line
 * @param column Current Stripe which has to set
 * @param left Defines rotation direction
 * @return next Column which has to set.
 */
uint8_t spiral(rgb_t color, uint8_t line, uint8_t column, bool left)
{
   uint8_t nextColumn, lastColumn, curColumn;
   
   rgb_t clr = {0,0,0};
   
   nextColumn = column;

   if (left)
   {
      if (column < STRIPES) 
            nextColumn++;
      else
            nextColumn = 1;
            
      if (column > 1) 
          lastColumn = column - 1;
      else 
          lastColumn = STRIPES;
   }
   else
   {
      if (column > 1) 
            nextColumn--;
      else
            nextColumn = STRIPES;
            
      if (column < STRIPES) 
          lastColumn = column + 1;
      else 
          lastColumn = 1;   
   }
    
    strip.setPixelColor(line,clr,lastColumn); // clear last Led
    
    strip.setPixelColor(line,color,column);
   
   return nextColumn;
}





